package com.dtsheep.rxjava.stduy.observable;

import rx.Observable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * ZipDemo
 *
 * <p>
 *     zip 操作符
 *     将多个 Observable 合并为一个，按顺序组合它们的发射项。
 * </p>
 *
 * @author chuanbai
 * @date 2024/5/17
 */
public class ZipDemo {


    public void zip01(){
        Observable<Integer> observable1 = Observable.just(1, 2, 3);
        Observable<String> observable2 = Observable.just("A", "B", "C");

        // 组合两个 Observable 成一个
        // 类似 stream 的 Bifunction
        Observable.zip(observable1, observable2, (a, b) -> a + " : " + b)
                .subscribe(res -> System.out.println(res)); // 这是一个 BiFunction，它接收来自两个 Observable 的数据并组合它们

//        1 : A
//        2 : B
//        3 : C
    }

    
    /**
     * zip 操作符
     * zip 操作符通常用于当你想要基于多个数据流进行某些操作时想要将来自两个或多个不同源的数据组合成单个复合项时
     *
     * @param
     * @return 
     * @author chuanbai
     * @date ${DATE}
     */
    public void zip02(){
        // 定义 Observable
        Observable<List<String>> observable1 = Observable.just(Arrays.asList("苹果" , "糖葫芦"));
        Observable<String> observable2 = Observable.just("香蕉");
        Observable<String> observable3 = Observable.just("桃子");
        Observable<String> observable4 = Observable.just("栗子");

        // 组合 Observable 的集合
        List<Observable<?>> obsList = Arrays.asList(observable1, observable2, observable3, observable4);


        // zip 处理元素
        Observable<Object[]> observable = Observable.zip(
                obsList,
                results -> {
                    // 假设第一个 Observable 发射的是 List 类型，我们想要修改它
                    List<String> originalList = (List) results[0];
                    List<String> modifiedList = new ArrayList<>(originalList);
                    for (int i = 0; i < modifiedList.size(); i++) {
                        String s = modifiedList.get(i);
                        if ("苹果".equals(s)) {
                            modifiedList.set(i, "ceshi");
                        }
                    }
                    modifiedList.add("添加");
                    return new Object[]{modifiedList, results[1], results[2]};
                }
        ).onErrorReturn(e -> new Throwable[]{e});

        observable.subscribe(obj-> {
            for (int i = 0; i < obj.length; i++) {
                System.out.println(obj[i]);
            }
        });


    }

    public static void main(String[] args) {
        ZipDemo zipDemo = new ZipDemo();
        zipDemo.zip01();
        zipDemo.zip02();
    }
}
